import sys
import os
from read_csi_from_file import read_from_csifile
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from statsmodels.tsa.stattools import adfuller
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd


def getmod(arr):
    return np.abs(arr)

def getmodl(list):
    return [getmod(arr) for arr in list]

def getphase(arr):
    return np.angle(arr)

def getphasel(list):
    return [getphase(arr) for arr in list]

'''
计算相位差
'''
def get_phase_dif(csi1,csi2):
    csi_t = [0] * 30
    for i in range(30):
        if csi1[i] >= 0 and csi2[i] >= 0:
            if csi1[i] >= csi2[i]:
                temp = csi1[i] - csi2[i]
            else:
                temp = csi2[i] - csi1[i]
        elif csi1[i] > 0 and csi2[i] < 0:
            t = csi1[i] - np.pi
            if csi2[i] > t:
                temp = np.pi - csi2[i] + t
            else:
                temp = np.pi * 2 + csi2[i] - csi1[i]
        elif csi1[i] < 0 and csi2[i] > 0:
            t = csi2[i] - np.pi
            if csi1[i] >= t:
                temp = np.pi - csi1[i] + t
            else:
                temp = np.pi * 2 + csi1[i] - csi2[i]
        else:
            if csi1[i] >= csi2[i]:
                temp = csi1[i] - csi2[i]
            else:
                temp = csi2[i] - csi1[i]

        csi_t[i] = temp

    return csi_t

'''
相位扩展
'''
def phase_expend(dat):
    csi_pha_exp = [0] * 30
    csi_pha_exp[0] = dat[0]
    for i in range(1,30):
        if (dat[i] - dat[i-1])>=np.pi:
            csi_pha_exp[i] = csi_pha_exp[i-1] + (dat[i] - dat[i-1] - 2*np.pi)
        elif (dat[i] - dat[i-1])<= -np.pi:
            csi_pha_exp[i] = csi_pha_exp[i-1] + (dat[i] - dat[i-1] + 2 * np.pi)
        else:
            csi_pha_exp[i] = csi_pha_exp[i-1] + (dat[i] - dat[i-1])
    return csi_pha_exp


'''
相位线性变换
'''
def phase_linear_trans(dat):
    csi_pha_expend = phase_expend(dat)
    csi_pha_trans = [0] * 30
    m = [-28, -26, -24, -22, -20, -18, -16, -14, -12, -10,  -8,  -6,  -4, -2, -1, 1,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 28]

    k = (csi_pha_expend[29] - csi_pha_expend[0])/(m[29] - m[0]) #斜率
    b = np.sum(csi_pha_expend)/30 #截距

    for i in range(30):
        csi_pha_trans[i] = csi_pha_expend[i] - k * m[i] - b

    return csi_pha_trans

'''
Hampel滤波
'''
def hampel_filter(dat):
    frame = 5  # hample滤波器的窗口至少为7
    L = 3
    z_ham = []
    for i in range(frame, len(dat[frame:-frame])):
        l = dat[i - frame:i + frame]
        d = np.median(l)
        s = l - d
        m = np.median(s)
        MAD = 1.4826 * m
        if abs(l[0] - d) < L * MAD:
            z_ham.append(l[0])
        else:
            z_ham.append(d)
    s = np.arange(len(z_ham))
    b, a = signal.butter(3, 0.03, 'low')
    sf = signal.filtfilt(b, a, z_ham)
    plt.plot(s, sf)
    z_ham = sf
    return z_ham

'''
时域转换到频域,获取频域特征--频域方差
'''
def freq_trans(dat):
    frame = 7
    z_fft = []
    for i in range(frame, len(dat[frame:-frame])):
        l = dat[i - frame:i + frame]
        l_fft = np.fft.fft(l)
        a= np.std(l_fft) #频域方差
        z_fft.append(a)

    return z_fft

'''
获取时域特征
'''
def time_trans(dat):
    frame = 7
    z_var = []
    for i in range(frame, len(dat[frame:-frame])):
        l = dat[i - frame:i + frame]
        l_var = np.std(l)
        z_var.append(l_var)

    return z_var

'''
计算信号短时能量
'''
def calEnergy(dat):
    frame = 7
    z_energy = []
    for i in range(frame, len(dat[frame:-frame])):
        l = dat[i - frame:i + frame]
        a = np.sum(np.square(l))
        z_energy.append(a)

    return z_energy


'''
CSI原始数据转换
'''
def CSI_trans(filename):

    f = read_from_csifile(filename)

    print(len(f))
    csi_amp1 = []
    csi_amp2 = []
    csi_pha1 = []
    csi_pha2 = []
    rssia = []
    csi_pha_dif = []

    for dat in f:
        amp1 = getmodl(dat.csi[0][0])
        if dat.Nrx == 2:
            amp2 = getmodl(dat.csi[0][1])
        pha1 = phase_linear_trans(getphasel(dat.csi[0][0]))
        if dat.Nrx == 2:
            pha2 = phase_linear_trans(getphasel(dat.csi[0][1]))
        rssi1 = dat.rssi_a

        if len(amp1) == 30:
            csi_amp1.append(amp1)
        if len(amp2) == 30:
            csi_amp2.append(amp2)
        if len(pha1) == 30:
            csi_pha1.append(pha1)
        if len(pha2) == 30:
            csi_pha2.append(pha2)
        rssia.append(rssi1)
        # print(rssia)
        # 计算相位差
        if dat.Nrx == 2:
            csi_pha_dif.append(get_phase_dif(pha1, pha2))

    return csi_pha1


'''
制作样本
'''
def get_sample():
    # 获取相位数据，制作样本
    filename1 = "../jingzhi1.csi"
    csi_pha_train = CSI_trans(filename1)
    # print(len(csi_pha_train))

    data = pd.read_csv("../jingzhi1_label.csv")
    csi_pha_label = list(data['label'])
    # print(len(csi_pha_label))

    filename2 = "../fuwocheng1.csi"
    temp = CSI_trans(filename2)
    csi_pha_train.extend(temp)

    filename3 = "../jingzhi.csi"
    temp = CSI_trans(filename3)
    csi_pha_train.extend(temp)
    print(len(csi_pha_train))

    data = pd.read_csv("../fuwocheng1_label.csv")
    temp = list(data['label'])
    csi_pha_label.extend(temp)

    data = pd.read_csv("../jingzhi_label.csv")
    temp = list(data['label'])
    csi_pha_label.extend(temp)
    print(len(csi_pha_label))

    return csi_pha_train,csi_pha_label


'''
利用相位判断有人与没人的状态
利用SVM进行训练
csi_pha_train 训练样本
csi_pha_label 样本标签
'''
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split as ts
from sklearn.externals import joblib

def svm_c(csi_pha_train,csi_pha_label):
    X_train, X_test, y_train, y_test = ts(csi_pha_train, csi_pha_label, test_size=0.3)
    # rbf核函数
    svc = SVC(kernel='rbf')
    svc.fit(X_train,y_train)
    score = svc.score(X_test,y_test)
    print(score)
    # pred = svc.predict(csi_pha_train)
    # return pred
    joblib.dump(svc,"../SVM_Model.m")


csi_pha_train,csi_pha_label = get_sample()
svm_c(csi_pha_train,csi_pha_label)


